Conversation
05e5d00 to
bc13315
Compare
bc13315 to
83ca882
Compare
f435ba9 to
3b09739
Compare
lib/ferrum/frame/dom.rb
Outdated
| end | ||
|
|
||
| def wait_for_selector(css: nil, xpath: nil, timeout: 3000, interval: 100) | ||
| evaluate_func(%( |
There was a problem hiding this comment.
There was a problem hiding this comment.
it makes sense, will change, thanks!
lib/ferrum/frame/dom.rb
Outdated
| waitForSelector(resolve, reject); | ||
| }); | ||
| } | ||
| ), css || xpath, css.nil? && !xpath.nil?, timeout, interval, awaitPromise: true) |
There was a problem hiding this comment.
I was feeling like this arguments list was a little crowded, and also noticed this function could be incorrectly called without raising an exception: one of css or xpath is required, but not handled. What do you think about something like this:
def wait_for_selector(css: nil, xpath: nil, timeout: 3000, interval: 100)
raise ArgumentError.new("Provide :css or :xpath, but not both") if css && xpath
raise ArgumentError.new("Provide :css or :xpath") unless css || xpath
evaluate_func(<<~JS, css || xpath, !!xpath, timeout, interval, awaitPromise: true)
function(selector, isXpath, timeout, interval) {
var attempts = 0;
The guard clauses protect the arguments from being called incorrectly, and also simplify the resolution to isXpath, since it can now only be one or the other.
There was a problem hiding this comment.
well, it looks like too much for one method to be responsible for selector/XPath and also for validations.
However, I see the confusing point here as well. In this case, I think we should use simple methods for more clear API, like those:
def wait_for_selector(css, **options)
wait_for_element(css: css, **options)
end
def wait_for_xpath(xpath, **options)
wait_for_element(xpath: xpath, **options)
endThe point to merge two ways of element-find logic was a follow a DRY principle for a common JS function, especially this part:
var element = isXpath
? document.evaluate(selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
: document.querySelector(selector);therefore, I think, we can find a way to refactor it with a private function by passing a js function, gimme see closer, will do an update soon.
There was a problem hiding this comment.
Nice one, yes, I think this is a better direction. Consider wait_for_css rather than wait_for_selector as a selector could generically mean css or xpath. It makes the expected arg more clear.
|
Can this be merged? Do the linters need to be changed or do we want to follow the linter advice? |
|
I'm sorry guys, with all this stuff happening I barely find time for open source now, hope it's going to calm down soon. |
|
If anyone needs a simple substitute of timeout_true = lambda do |timeout = 1, &block|
Timeout.timeout timeout do
block.yield or (sleep 0.1; redo)
end
end |
|
Any chance we could have a reviewer review and accept this? It would be very nice to have in the main Gem. Thanks! |
|
Would this be simpler? class Ferrum::Browser
def wait_for(want, wait:1, step:0.1)
meth = want.start_with?('/') ? :at_xpath : :at_css
until node = send(meth, want)
(wait -= step) > 0 ? sleep(step) : break
end
node
end
end |



closes #82